package nl.ajonker.railroad.ui;

import static nl.ajonker.railroad.ui.Orientation.E_N;
import static nl.ajonker.railroad.ui.Orientation.E_W;
import static nl.ajonker.railroad.ui.Orientation.N_W;
import static nl.ajonker.railroad.ui.Orientation.S_E;
import static nl.ajonker.railroad.ui.Orientation.W_S;

import java.awt.Container;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;

import javax.swing.JFrame;

import nl.ajonker.railroad.dl.CornerRail;
import nl.ajonker.railroad.dl.Rail;
import nl.ajonker.railroad.dl.StraightRail;
import nl.ajonker.railroad.dl.SwitchRail;
import nl.ajonker.railroad.dl.Track;
import nl.ajonker.railroad.ui.drawcommand.DrawCommand;

public class RailRoad implements MouseMotionListener, MouseListener {
	// private final int TICK = 300;
	private JFrame frame;
	private Container content;
	private Track track;
	private final Point start = new Point(100, 50);

	/**
	 * Launch the application.
	 */
	public static void main(final String[] args) {
		EventQueue.invokeLater(new Runnable() {
			@Override
			public void run() {
				try {
					final RailRoad window = new RailRoad();
					window.frame.setVisible(true);
					window.start();
				} catch (final Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	/**
	 * Create the application.
	 */
	public RailRoad() {
		initialize();
	}

	/**
	 * Initialize the contents of the frame.
	 */
	private void initialize() {
		frame = new JFrame() {
			private static final long serialVersionUID = 1L;

			@Override
			public void paint(final Graphics g) {
				super.paint(g);
				repaintRails();
				// System.out.println("Paint");
			}
		};
		frame.setBounds(100, 100, 450, 300);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		content = frame.getContentPane();
		track = new Track();

		final Rail railA = new SwitchRail();
		track.addRail(railA);

		// Train train = new Train();
		// track.addTrain(train);
		// railA.acceptTrain(train);

		track.addRail(new StraightRail());
		track.addRail(new CornerRail(W_S));
		track.addRail(new CornerRail(N_W));
		track.addRail(new StraightRail(E_W));
		track.addRail(new StraightRail(E_W));
		track.addRail(new CornerRail(E_N));
		track.addRail(new CornerRail(S_E));

		track.finish();

		// TrainMover trainMover = new TrainMover(track, this);
		// Timer timer = new Timer(TICK, trainMover);
		// timer.setInitialDelay(TICK);
		// timer.start();
	}

	public void start() {
		repaintRails();
		content.addMouseMotionListener(this);
		content.addMouseListener(this);
	}

	public void repaintRails() {
		final Graphics2D graphics2d = (Graphics2D) content.getGraphics();
		Point p = new Point(start);
		for (final Rail rail : track.getRails()) {
			p = rail.getDrawCommand().drawRail(graphics2d, p, rail);
		}
	}

	@Override
	public void mouseMoved(final MouseEvent e) {
		final Graphics2D g2d = (Graphics2D) content.getGraphics();
		final Point p = e.getPoint();
		for (final Rail rail : track.getRails()) {
			final DrawCommand cmd = rail.getDrawCommand();
			if (cmd.contains(p)) {
				cmd.drawMouseOver(g2d);
			} else {
				cmd.removeMouseOver(g2d, frame.getBackground());
			}
		}
	}

	@Override
	public void mouseDragged(final MouseEvent e) {
		// do nothing
	}

	@Override
	public void mouseClicked(MouseEvent e) {
		final Graphics2D g2d = (Graphics2D) content.getGraphics();
		final Point p = e.getPoint();
		for (final Rail rail : track.getRails()) {
			final DrawCommand cmd = rail.getDrawCommand();
			if (cmd.contains(p)) {
				cmd.onClick();
				cmd.drawRail(g2d);
			}
		}
	}

	@Override
	public void mouseEntered(MouseEvent arg0) {
		// do nothing

	}

	@Override
	public void mouseExited(MouseEvent arg0) {
		// do nothing
	}

	@Override
	public void mousePressed(MouseEvent arg0) {
		// do nothing
	}

	@Override
	public void mouseReleased(MouseEvent arg0) {
		// do nothing
	}

}
